﻿using System;
using System.Collections.Generic;

using System.Text;

namespace RoughJs.Ast
{

    /// <summary>
    /// 2010-01-5 ----- 2010-01-29
    /// 陈曦 1.0
    /// Microsoft Public License (Ms-PL)
    ///This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
    ///1. Definitions
    ///The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
    ///A "contribution" is the original software, or any additions or changes to the software.
    ///A "contributor" is any person that distributes its contribution under this license.
    ///"Licensed patents" are a contributor's patent claims that read directly on its contribution.
    ///2. Grant of Rights
    ///(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
    ///(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
    ///3. Conditions and Limitations
    ///(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
    ///(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
    ///(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
    ///(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
    ///(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. 
    /// 
    /// 脚本化接口
    /// </summary>
    public interface Scriptable
    {
        /// <summary>
        /// 获得了由这个Java类实现对象的集合名称。这对应于[[类]]在ECMA的操作和使用
        ///由Object.prototype.toString（）在ECMA的。
        /// </summary>
        /// <returns></returns>
        String getClassName();
        /// <summary>
        /// 根据对象得到属性
        /// 从对象上查找属性而且如果找到返回相关联的值。
        /// 如果没有找到返回 NOT_FOUND 
        /// 注意这个方法不会遍历 prototype链
        /// 这个不同于ECMA的get操作符
        /// 根据不同的属性选择器调用方法或者使用二进制形式
        /// 
        /// JavaScript code         Java code
        /// a.b                     a.get("b", a)
        /// a["foo"]                a.get("foo", a)
        /// a[3]                    a.get(3, a)
        /// a["3"]                  a.get(3, a)
        /// a[3.0]                  a.get(3, a)
        /// a["3.0"]                a.get("3.0", a)
        /// a[1.1]                  a.get("1.1", a)
        /// a[-4]                   a.get(-4, a)
        /// 
        /// 
        /// 这个值将会返回为有限的形式
        /// java.lang.Boolean objects
        ///  java.lang.String objects
        /// java.lang.Number objects
        /// org.mozilla.javascript.Scriptable objects
        /// null
        /// The value returned by Context.getUndefinedValue()
        /// </summary>
        /// <param name="name">属性名</param>
        /// <param name="start">查寻的开始</param>
        /// <returns></returns>
        Object get(String name, Scriptable start);

        /// <summary>
        /// 根据索引从选择的对象中取得属性
        /// </summary>
        /// <param name="index">索引</param>
        /// <param name="start">开始的位置</param>
        /// <returns>返回属性值（可能为空）或者为NOT_FOUND</returns>
        Object get(int index, Scriptable start);

        /// <summary>
        /// 属性是否被定义在一个对象，但不遍历prototyp
        /// 
        /// 根据名字去得到方法
        /// 
        /// </summary>
        /// <param name="name">属性名</param>
        /// <param name="start">查找的开始</param>
        /// <returns></returns>
        bool has(String name, Scriptable start);

        /// <summary>
        /// 根据索引判断是否有
        /// </summary>
        /// <param name="index"></param>
        /// <param name="start"></param>
        /// <returns></returns>
        bool has(int index, Scriptable start);

        /// <summary>
        /// 设置这个对象的属性
        /// 这个属性被一个字符串定义
        /// 这个可能的值被get定义
        /// 这个类可能忽略对read-only类型属性的调用
        /// 
        /// 因为属性被定义在prototype 链
        /// 使用putProperty 在ScriptableObject
        /// 
        /// 注意如果一个属性被做为一个对象定义在一个prototype中
        /// 这个时候评测o.a=23将会被prototype调用
        /// 为了保持JavaScript的语义,这是脚本化对象去修改
        /// 
        /// 这样的设计允许属性被定义在prototyp而且实现了从prototype到java类的转换
        /// 
        /// 这个值将被Context.getUndefinedValue()返回
        /// 这个值将会返回为有限的形式
        /// java.lang.Boolean objects
        ///  java.lang.String objects
        /// java.lang.Number objects
        /// org.mozilla.javascript.Scriptable objects
        /// null
        /// 任何一个java对象会被包装在一个Scriptable里面Context.toObject    
        /// 这个允许一个javascript对象包含一个java对象做为一个值.
        /// 
        /// 注意他会被调用在运行之前
        /// 注意，此方法预计不会遍历原型链，
        /// 这是有别于在ECMA [[put]]操作。
        /// 
        /// </summary>
        /// <param name="name">属性名</param>
        /// <param name="start">开始位置</param>
        /// <param name="value">值</param>
        void put(String name, Scriptable start, Object value);
        /// <summary>
        /// 设置这个索引属性
        /// </summary>
        /// <param name="index"></param>
        /// <param name="start"></param>
        /// <param name="value"></param>
        void put(int index, Scriptable start, Object value);

        /// <summary>
        /// 移除此对象的属性
        /// 此操作对应于ECMA[[delete]],但是无法返回结果.
        /// 
        /// 如果这个方法存在运行时将会去调用。
        /// 在这个方法被调用，运行时将调用Scriptable.
        /// ECMA 11.4.1.中定义这个操作将会返回bool值
        /// </summary>
        /// <param name="name">属性名</param>
        void delete(String name);

        /// <summary>
        /// 根据索引来删除
        /// </summary>
        /// <param name="index">索引</param>
        void delete(int index);

        /// <summary>
        /// 得到prototype对象
        /// </summary>
        /// <returns>返回prototype</returns>
        Scriptable getPrototype();

        /// <summary>
        /// 设置对象的prototype
        /// </summary>
        /// <param name="prototype">prototype</param>
        void setPrototype(Scriptable prototype);

        /// <summary>
        /// 获得对象的父域
        /// </summary>
        /// <returns>返回父域</returns>
        Scriptable getParentScope();

        /// <summary>
        /// 设置父域
        /// </summary>
        /// <param name="parent">父域</param>
        void setParentScope(Scriptable parent);

        /// <summary>
        /// 得到一个id的属性数据
        /// 
        /// 不是所有的属性id都可以返回
        /// 那些不能被枚举的id不可以返回
        /// </summary>
        /// <returns>返回一组对象,内容是String或者是数字</returns>
        Object[] getIds();

        /// <summary>
        /// 根据预先给定值得到对象的默认值
        /// 这些给定值是String.class 是String 类型
        /// Number.class是数字类型
        /// Scriptable.class 是对象类型
        /// Boolean.class 是bool类型
        /// 参见ECMA 8.6.2.6.
        /// </summary>
        /// <param name="hint"></param>
        /// <returns></returns>
        Object getDefaultValue(Type hint);

        /// <summary>
        /// instanceof 操作
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        bool hasInstance(Scriptable instance);
    }
}
